package com.sdu.game.websocket;

import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

//用户语音交流
@ServerEndpoint("/webSocket/chat/{sid}")
@Component
public class Chat {
    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。

    private static AtomicInteger onlineNum = new AtomicInteger();

    //concurrent包的线程安全Set，存在发送消息的用户
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();



    //发送消息，接收聊天信息后，给所有房间用户推送消息
    public void sendMessage(Session session, String message) throws IOException {
        if(session != null){
            synchronized (session) {
//                System.out.println("发送数据：" + message);
                session.getBasicRemote().sendText(message);
            }
        }
    }
    //给指定用户发送信息
    public void sendInfo(String userName, String message){
        Session session = sessionPools.get(userName);
        try {
            sendMessage(session, message);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void sendInfouser(String userName, String user){
        Session session = sessionPools.get(userName);
        try {
            if(session != null){
                synchronized (session) {
//                System.out.println("发送数据：" + message);
                    session.getBasicRemote().sendText(user);
                    System.out.println("类发送成功");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //建立连接成功调用，连接成功只需要将用户信息加入则可，消息处理模块主要在消息发送中
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "sid") String userName){
        //使用用户id来作为session的唯一判断标准和数据库中的房间中的用户对应
        System.out.println(userName);
        Session sessiont= sessionPools.get(userName);

        //判断用户是否已经存在，同一人不能同时加入两个房间
        try {
            if(sessiont == null){
                synchronized (session) {
//                System.out.println("发送数据：" + message);
                    System.out.println("ssssssssssssssssssssssss");
                    sessionPools.put(userName, session);
                    addOnlineCount();//在线人数
//                    session.getBasicRemote().sendText(user);
//                    System.out.println("类发送成功");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }



        System.out.println(sessionPools.toString());

        try {
            sendMessage(session, "欢迎" + userName + "加入连接！");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //关闭连接时调用
    //当玩家退出时需要将玩家连接关闭的同时，将其从数据库中删除
    @OnClose
    public void onClose(@PathParam(value = "sid") String userName){
        sessionPools.remove(userName);
        subOnlineCount();

        //数据库操作，userId，在玩家表中找到该玩家得到房间号，然后将玩家删除，同时在房间表中将用户删除

        System.out.println(userName + "断开webSocket连接！当前人数为" + onlineNum);
    }


    //收到客户端信息
    //用户通过send发送的数据被接收后直接返回给
    @OnMessage
    public void onMessage(String message,Session session) throws IOException{
//        message = "客户端：" + message + ",已收到";
        //用户发来的信息中包含该用户id,房间id和所发送的信息，之后将该用户的昵称和所发送的信息广播给该房间内的人


        //从数据库中得到房间内用户的ID用来广播数据使用
        //只考虑一个房间的情况下直接将收到的信息全部回传给所有用户


        for (Session sessiont: sessionPools.values()) {
            try {
                sendMessage(sessiont, message);
            } catch(Exception e){
                e.printStackTrace();
                continue;
            }
        }

    }


    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable){
        System.out.println("发生错误");
        throwable.printStackTrace();
    }

    public static void addOnlineCount(){
        onlineNum.incrementAndGet();
    }

    public static void subOnlineCount() {
        onlineNum.decrementAndGet();
    }

}